// TypeSystem.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "runtime_exceptions.h"
#include "runtime_types.h"
#include "runtime_typecasts.h"

#include <boost/multi_array.hpp>
#include <boost/variant.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <iostream>

namespace detail {
	namespace mpl = boost::mpl;

	template <typename T, size_t Mindim = 1, size_t Maxdim = 5>
	struct make_generic_array_storage
	{
		template<typename N> struct to_array_f { typedef boost::multi_array<T, N::value> type; };

		typedef typename mpl::transform<
			mpl::range_c<size_t, Mindim, Maxdim>, 
			to_array_f<mpl::_1>,
			mpl::back_inserter<mpl::vector<> > 
		>::type list;

		typedef typename boost::make_variant_over<list>::type type;
	};
}

template <typename T>
struct SafeArray
{
	template <typename Rhs> SafeArray& operator=(Rhs const& rhs) {
		_storage = rhs;
		return *this;
	}

	template <size_t N> boost::multi_array<T, N>		& get()     { 
		try{
			return boost::get<boost::multi_array<T, N> >(_storage);
		}catch(boost::bad_get){
			throw runtimeException(runtimeException::fbSubscriptOutOfRange);
		}
	}
	template <size_t N> boost::multi_array<T, N> const& get() const {
		try{
			return boost::get<boost::multi_array<T, N> >(_storage);
		}catch(boost::bad_get){
			throw runtimeException(runtimeException::fbSubscriptOutOfRange);
		}
	}

private:
	typename detail::make_generic_array_storage<T>::type _storage;
};

String ffftfunction(Long x,Integer& xg,Long& z);
Long factorial(Long n);
Boolean booltest();
void main() {
	
	factorial(777);
	booltest();
	
	


}

#include "../out.cpp"
